#coding=utf-8
import zlib, urllib,time
from BeautifulSoup import BeautifulSoup

import socket
socket.setdefaulttimeout(10)

def get_soup(url):

    def deflate(raw_data):
        decoder = zlib.decompressobj()
        header = "x\x9c"
        data = decoder.decompress(header + raw_data)
        return data

    while True:
        try:
            raw_data = urllib.urlopen(url).read()
            data = deflate(raw_data)
            break

        except (IOError,socket.timeout, zlib.error) , e:
            print 'Error:', e, 'Now try again.'
            time.sleep(0.05)

    udata = data.decode('gb18030', 'ignore')
    return BeautifulSoup(udata)

def get_1st_soup(code, exdate):
    url = "http://bill.finance.sina.com.cn/bill/history_trade_item.php?stock_code=sh%s&date=%s"%(code, exdate)
    s = get_soup(url)
    return s

def get_deal_soup(code, exdate, number):
    url = "http://bill.finance.sina.com.cn/bill/history_trade_item.php?stock_code=sh%s&pages=%s&date=%s"%(code, str(number), exdate)
    s = get_soup(url)
    return s

def get_pageno(soup):

    for i in range(2, 250):
        txt = "[%s]"%str(i)
        t = soup.find(text = txt)
        if not t:
            #有这样种情况:一天有很少的成交量，但成交明细没有数据.
            #eg:http://bill.finance.sina.com.cn/bill/history_trade_item.php?stock_code=sh600369&date=20071210
            
            t1 = unicode('买盘', 'u8')
            t2 = unicode('卖盘', 'u8')
            t3 = unicode('中性盘', 'u8')
            m = soup.find(text=t1)
            if not m: m = soup.find(text=t2)
            if not m: m = soup.find(text=t3)
            if not m:return None
                     
            return i-1

def get_data_per_soup(soup):

    def get_bs(s):
        if s == '买盘':
            return 'b'
        elif s == '卖盘':
            return 's'
        else:
            return 'n'

    data = []

    t1 = unicode('买盘', 'u8')
    t2 = unicode('卖盘', 'u8')
    t3 = unicode('中性盘', 'u8')
    m = soup.find(text=t1)
    if not m: m = soup.find(text=t2)
    if not m: m = soup.find(text=t3)
    table = m.parent.parent.parent.parent

    for tr in table.findAll('tr'):
        d = []
        for c in tr.contents:
            f = c.font
            if not f: f = c
            d.append(f.string)
        d[1] = d[1][:-1]
        d[2] = d[2][:-1]
        d  = [i.encode('u8') for i in d]
        d[3] = get_bs(d[3])

        data.append(d)

    return data
    
class NoDealError(Exception):
    def __init__(self, code, exdate):
        self.code = code
        self.exdate = exdate
    def __str__(self):
        return "%s:no deal data from sina on %s"%(self.code, self.exdate)
        
def get_deal(code, exdate):
    data = []
    s1 = get_1st_soup(code, exdate)
    n = get_pageno(s1)
    if not n:
        raise NoDealError(code,exdate)
    #print n
    for i in range(n):
        s = get_deal_soup(code, exdate, i)
        d = get_data_per_soup(s)
        data = data + d

    return data

if __name__ == '__main__':
    data = get_deal('600332', '2007-09-04')
    print data 
